home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ZED3DSRC.ZIP
/
ZSORT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-19
|
5KB
|
274 lines
#include <stdio.h>
#include <stdlib.h>
#include <zsort.h>
void xform_pointcollection
(pointcollection *p,
affine *xform,
pipe_point *xpoints)
{
long x,y,z;
for(x=0;x<p->numpoints;x++) /* for each point... */
{
/* transform it */
affine_xform(xform,p->vertex[x].location,
xpoints[x].point.location);
#ifdef __vertexnormals__
mat_mul_vec(xpoints[x].point.normal,
xform->m,
p->vertex[x].normal);
/* rotate vertex normals */
#endif
xpoints[x].point.clipping=p->vertex[x].clipping;
/* copy clipping information which could be required in
a later part of the pipeline */
if(xpoints[x].point.location[2]>0)
{
xpoints[x].scr_X=div(xpoints[x].point.location[0],
xpoints[x].point.location[2]);
xpoints[x].scr_Y=div(xpoints[x].point.location[1],
xpoints[x].point.location[2]);
}
}
}
pipeline *alloc_pipeline(int numpoints, int numfaces, int numindex)
{
pipeline *p;
p=malloc(sizeof(pipeline));
if(!p)
return 0;
p->numfaces=numfaces;
p->numindex=numindex;
p->numpoints=numpoints;
p->pbase=malloc(sizeof(pipe_point)*numpoints);
p->fbase=malloc(sizeof(face)*numfaces);
p->ibase=malloc(sizeof(long)*numindex);
p->index1=malloc(sizeof(long)*numfaces);
p->index2=malloc(sizeof(long)*numfaces);
p->minZ=malloc(sizeof(long)*numfaces);
p->maxZ=malloc(sizeof(long)*numfaces);
if(!p->pbase||
!p->fbase||
!p->ibase||
!p->index1||
!p->index2||
!p->minZ||
!p->maxZ
)
{
free_pipeline(p);
return 0;
}
reset_pipeline(p);
return p;
}
void free_pipeline(pipeline *p)
{
if(p)
{
if(p->pbase)
{
free(p->pbase);
p->pbase=0;
}
if(p->fbase)
{
free(p->fbase);
p->fbase=0;
}
if(p->ibase)
{
free(p->ibase);
p->ibase=0;
}
if(p->index1)
{
free(p->index1);
p->index1=0;
}
if(p->index2)
{
free(p->index2);
p->index1=0;
}
if(p->minZ)
{
free(p->minZ);
p->index1=0;
}
if(p->maxZ)
{
free(p->maxZ);
p->index1=0;
}
p->numindex=0;
p->numpoints=0;
p->numfaces=0;
free(p);
}
}
void reset_pipeline(pipeline *p)
{
p->pptr=0;
p->fptr=0;
p->iptr=0;
}
void cull_object(object *o, pipeline *p, affine *xform)
{
long a,b,c,x,y,z;
face *f,*g;
pipe_point *pt;
vector u;
REAL D;
pt=p->pbase+p->pptr;
xform_pointcollection(o->pts_data,xform,pt);
for(a=0;a<o->pts_data->numpoints;a++)
{
pt[a].point.clipping=
o->pts_data->vertex[a].clipping;
}
f=o->face_data->face;
for(a=0;a<o->face_data->numfaces;a++,f++)
{
/* backface cull. dot product of vector from eye to a point in
face with normal vector of face */
mat_mul_vec(u,xform->m,f->normal);
D=vec_dot(u, pt[*f->index].point.location);
if(D>=floattoreal(0.0))
{
/* clip */
for(b=0;b<f->numpoints;b++)
pt[f->index[b]].point.clipping--;
}
else
{
/* output face to pipeline */
g=p->fbase+p->fptr;
g->index=p->ibase+p->iptr;
g->numpoints=f->numpoints;
copyvector(g->normal,u);
g->D=D;
for(b=0;b<f->numpoints;b++)
g->index[b]=f->index[b]+p->pptr;
/* update pointers */
p->iptr+=f->numpoints;
p->fptr++;
}
}
/* now all faces are properly output and culled. we need only do
vertices now */
p->pptr+=o->pts_data->numpoints;
}
long *sort_pipeline(pipeline *p)
{
long a,b,c;
REAL A,B;
face *f;
pipe_point *pt;
f=p->fbase;
pt=p->pbase;
for(a=0;a<p->fptr;a++,f++)
{
A=pt[f->index[0]].point.location[2];
B=A;
for(b=1;b<f->numpoints;b++)
{
c=f->index[b];
if(pt[c].point.location[2]<A)
A=pt[c].point.location[2];
else if(pt[c].point.location[2]>B)
B=pt[c].point.location[2];
}
p->index1[a]=a;
p->minZ[a]=realtofixed(A);
p->maxZ[a]=realtofixed(B);
}
bytesort(p->maxZ,p->index1,p->index2,p->fptr,0);
bytesort(p->maxZ,p->index2,p->index1,p->fptr,1);
bytesort(p->maxZ,p->index1,p->index2,p->fptr,2);
bytesort(p->maxZ,p->index2,p->index1,p->fptr,3);
return p->index1;
}
#define getbyte(x,bitshift) (((x)>>(bitshift))&0xff)
void bytesort(long *data, long *indexin, long *indexout, long itemcount,
int bytenumber)
{
long count[257];
long a,b,c;
for(a=0;a<=256;a++)
count[a]=0;
bytenumber*=8;
for(a=0;a<itemcount;a++)
{
b=getbyte(data[indexin[a]],bytenumber);
count[b+1]++;
}
for(a=1;a<256;a++)
count[a]+=count[a-1];
for(a=0;a<itemcount;a++)
{
b=getbyte(data[indexin[a]],bytenumber);
indexout[count[b]]=indexin[a];
count[b]++;
}
}